Expression syntax

Several features let you evaluate and manipulate variables using a compact expression language. The same syntax is used in all of the following places:

The expression syntax is Python-like – if you are familiar with basic Python expressions, it will feel natural. This page describes the operators and functions that are available (only a restricted, safe subset is supported, as noted below).

Variable names vs. variable expansion

Inside an expression, refer to a variable by its name, “as is” – do not wrap it in curly brackets. Curly brackets ({var} / {{var}}) are only used when expanding a variable into surrounding text.

Enclose string values that you compare against in quotes, for example status == "active".

Safety

Expressions are evaluated in a restricted, sandboxed environment. Only the operators and functions listed on this page are available – arbitrary code, imports, loops, and unlisted functions (for example eval, any, isinstance) are rejected and produce an evaluation error.

Values and types

You can use the following kinds of values in an expression:

Value Examples
Variable reference age, customer_name, visits_count
String literal "active", "+1800..."
Number 18, 3.14
Boolean True, False
List ("John", "Jack", "Jonathan"), [1, 2, 3]

A variable keeps the type it was assigned. Numbers and booleans written literally are treated as numeric / boolean. When a variable holds text (for example a value coming from entity extraction or from a NAME = VALUE configuration), use the type-casting functions to convert it before a numeric or boolean comparison – for example int(age) > 18.

Comparison operators

Operator Meaning
== equal
!= not equal
< <= less than / less than or equal
> >= greater than / greater than or equal
age >= 18
status == "active"

Comparisons can also be chained, for example 0 < age < 120 or "08:00:00" <= current_time < "18:00:00".

You can also test a string variable for “has a value” by specifying its name alone (an empty string is treated as false):

{{#if customer_name}}

Logical operators

Use and, or, and not to combine conditions:

is_admin and age > 18
not is_guest

Arithmetic operators

Mainly used in Calculate node statements and ((...)) derivations:

Operator Meaning
+ addition (also string concatenation)
- subtraction
* multiplication
/ division
// integer division
% remainder (modulo)
** exponentiation
total_participants = adults_num + children_num
remaining = total - used

Membership (array) operators

Use in and not in to test whether a value is contained in a list, or whether a substring appears in a string. Specify lists as a comma-separated set of values enclosed in brackets.

person_name in ("John", "Jack", "Jonathan")
"please leave a message" in user_utterance

Conditional (ternary) expression

Use value_if_true if condition else value_if_false to choose between two values in a single expression. This is especially useful in Calculate node statements and ((...)) derivations:

greeting = "Hi" if informal else "Good day"

Indexing and slicing

You can index and slice string (and list) values using square brackets, including negative indexes:

caller[0]
caller[1:]
caller[-1]

Brackets

Use brackets to group sub-expressions and to write multi-line conditions:

{{#if (person_name == "John" or
       person_name == "Jack" or
       person_name == "Jonathan")}}
Say "Hello, Mr. J!"
{{/if}}

String methods

The following methods are available on string values:

Method Description
.lower() convert to lowercase
.upper() convert to uppercase
.strip() remove leading and trailing whitespace
.lstrip() remove leading whitespace
.rstrip() remove trailing whitespace
.startswith(prefix) True if the value starts with prefix
.endswith(suffix) True if the value ends with suffix
status.lower() == "active"
person_name.startswith("J")

Type-casting functions

Convert a value to a specific type. Each function accepts an optional second argument that is returned when the value is missing or cannot be converted; if you omit it, the default shown below is used.

Function Converts to Default on failure / missing
int(value[, default]) integer -1
float(value[, default]) float -1.0
bool(value[, default]) boolean False
str(value[, default]) string "" (empty string)
int(age) > 18
float(score, 0) >= 0.5
str(age) == "18"

For bool(), the strings "true", "yes", "y", and "1" (case-insensitive) convert to True; any other string converts to False. Numbers convert to False only when they are 0.

len()

len(value[, default]) returns the number of items in a string, list, tuple, dictionary, or set. For any other type (or a missing variable) it returns the default, which is 0 unless you specify otherwise.

len(customer_name) > 0
len(items) == 3

digits()

digits(value) returns a string containing only the digit characters found in value – every space, letter, and punctuation mark is removed. This is handy for normalizing a number the user spoke or typed with extra separators, for example turning my number is 1 2 3 into 123 before you compare, count, or validate it.

digits(user_response) == "123"
len(digits(phone_number)) == 10

A non-negative whole number is accepted too and its digits are returned as text. Anything with no digits to extract yields an empty string.

Validation functions

These helpers validate common identifier formats and return a boolean. Each accepts the value as a string or a number; spaces and dashes in string input are ignored.

Function Description
verify_credit_card(value) True if value is a valid credit-card number (13–19 digits passing the Luhn check).
verify_israeli_id(value) True if value is a valid Israeli ID number (teudat zehut) – 9 digits with a valid check digit.
{{#if verify_israeli_id(id)}} ID is valid {{#else}} Please repeat your ID {{/if}}

Undefined variables

If an expression references a variable that has not been set, that variable evaluates to a special “undefined” value:

This means you can safely reference variables that may not yet exist – for example {{#if order_total > 100}} simply yields false while order_total is still undefined, rather than failing.

Using time variables in conditions

How you reference a time variable (such as current_time) in a condition depends on where the condition runs: